﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using VswService_V7.Config;
using VswService_V7.OPC;
using VswService_V7.Sok;
using VswService_V7.Utility;
using VswService_V7.DataBase;
using VswService_V7.DataBase.Tables.L3INTERFACE;
using System.Data;
using VswService_V7.DataBase.Tables.L2INTERFACE;
using Oracle.ManagedDataAccess.Client;
using VswService_V7.Print;

namespace VswService_V7
{
    /// <summary>
    /// MainWindow.xaml interaction logic
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
        ServerConfig serverConfig;
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            LogHelper.WriteLog("L2 server started!");
            //Load configuration file
            try
            {
                //serverConfig = new ServerConfig();
                //XmlHelper.Save<ServerConfig>(serverConfig, AppDomain.CurrentDomain.BaseDirectory + "Config\\ServerConfig.xml");

                serverConfig = new ServerConfig();
                serverConfig = XmlHelper.Load<ServerConfig>(AppDomain.CurrentDomain.BaseDirectory + "Config\\ServerConfig.xml");
                int port = serverConfig.TCPServer.TcpServerPort;


                LogHelper.WriteLog("Loaded server configer success!");
                //***************************ORACLE CONNECT***************************
                OracleInitial();
                //***************************ORACLE CONNECT***************************
                //init TCP SERVER
                TcpServerInitial();
                //**************OPC
                OPCInitial();

                //******** print client init
                PrintClient.PrintClientHelper.SetPrintConfig(serverConfig.PrintClientSetting);

                //Monitor L3 event status
                Task.Run(() => MonitorL3Event());

            }
            catch (Exception ex)
            {
                LogHelper.WriteLog("L2 service start failed!", ex);
            }
        }

        private void Window_Closed(object sender, EventArgs e)
        {
            if (myServer != null)
                myServer.Stop();
        }

        #region Oracledatabase
        void OracleInitial()
        {
            OracleConnectionStringBuilder stringBuilder = new OracleConnectionStringBuilder();
            stringBuilder.UserID = serverConfig.OracleServer.UserId;
            stringBuilder.Password = serverConfig.OracleServer.Password;
            stringBuilder.DataSource = serverConfig.OracleServer.DataSource;
            stringBuilder.MaxPoolSize = serverConfig.OracleServer.MaxPoolSize;
            stringBuilder.MinPoolSize = serverConfig.OracleServer.MinPoolSize;
            stringBuilder.PersistSecurityInfo = true;
            stringBuilder.Pooling = true;
            stringBuilder.ConnectionTimeout = 10;
            bool result = OracleHelper.InitialConnectPool(stringBuilder);
            if (result)
            {
                LogHelper.WriteLog("Oracle connection ok");
                rect_database.Fill = Brushes.Green;
            }
            else
            {
                LogHelper.WriteLog("Oracle connection failed");
                rect_database.Fill = Brushes.Red;
            }
        }

        #endregion

        #region TCP Server
        MyServer myServer;
        /// <summary>
        /// TCP SERVER initialization
        /// -1 IP address format error!
        /// -2 Failed to open the listening port!
        /// -3 Server failed to start!
        /// 1 The server starts successfully!
        /// </summary>
        void TcpServerInitial()
        {
            //myServer = new MyServer(serverConfig.TCPServer.TcpServerPort);
            myServer = new MyServer(serverConfig.TCPServer.TcpServerIP, serverConfig.TCPServer.TcpServerPort);
            int state = myServer.Start();
            switch (state)
            {
                case 1:
                    {
                        txb_message.Text += "TcpServer：" + myServer.ServerIP + "：" + myServer.ServerPort + "Start success！\n";
                        rect_tcp.Fill = Brushes.Green;
                        break;
                    }

                case -1:
                    {
                        txb_message.Text += "IP Adress Illegal! \n";
                        rect_tcp.Fill = Brushes.Red;
                        break;
                    }

                case -2:
                    {
                        txb_message.Text += "Listening Port Open Failed！\n";
                        rect_tcp.Fill = Brushes.Red;
                        break;
                    }

                case -3:
                    {
                        txb_message.Text += "Tcp server start failed！\n";
                        rect_tcp.Fill = Brushes.Red;
                        break;
                    }

                default:
                    break;

            }

            //5. Pass to the interface output
            myServer.SessionChanged += SessionChange;
        }

        //四.
        private void SessionChange(object sender, SessionListChangedEventArgs e)
        {
            if (e.Action)
            {
                Dispatcher.Invoke(() => txb_message.Text += "Session Connect：" + e.SessionAdr + "  " + e.LastActive.ToLongTimeString() + "\n");
            }
            else
                Dispatcher.Invoke(() => txb_message.Text += "Session Disconnect：" + e.SessionAdr + "  " + e.LastActive.ToLongTimeString() + "\n");
        }


        #endregion

        #region Opc Client
        OpcDataFactory opc;

        void OPCInitial()
        {
            // Create client API server object
            opc = new OpcDataFactory(serverConfig.OPCServer, serverConfig.NodeConfig);
            opc.Connect();
            try
            {
                if (opc.IsConnected)
                {
                    opc.CreateSubscriptions();
                    rect_opc.Fill = Brushes.Green;
                }
                else
                    rect_opc.Fill = Brushes.Red;
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog("OPCInitial", ex);
                rect_opc.Fill = Brushes.Red;
                throw ex;
            }

        }
        #endregion

        #region L3Event  
        private async Task MonitorL3Event()
        {
            while (true)
            {
                try
                {
                    Dictionary<string, string> dic = L3INTF_EVENT.MonitorL3Infc_Event();
                    if (dic != null && dic.Count > 0)
                    {
                        foreach (KeyValuePair<string, string> kvp in dic)
                        {
                            switch (kvp.Value)
                            {
                                case L3INTF_EVENT.generalTask:
                                    {
                                        L3INTF_TASK_INFO.GeneralTask(kvp.Key);
                                        break;
                                    }
                                case L3INTF_EVENT.deleteTask:
                                    {
                                        L3INTF_TASK_DELETE.DeleteTask(kvp.Key);
                                        break;
                                    }
                                case L3INTF_EVENT.updateTask:
                                    {
                                        L3INTF_TASK_INFO.UpdateTask(kvp.Key);
                                        break;
                                    }
                                case L3INTF_EVENT.addStripstoTask:
                                    {
                                        L3INTF_STRIP_INFO.AddStripstoTask(kvp.Key);
                                        break;
                                    }
                                case L3INTF_EVENT.deleteStripfromTask:
                                    {
                                        L3INTF_STRIP_DELETE.DeleteStripfromTask(kvp.Key);
                                        break;
                                    }
                                case L3INTF_EVENT.updateStrip:
                                    {
                                        L3INTF_STRIP_INFO.UpdateStrip(kvp.Key);
                                        break;
                                    }
                                case L3INTF_EVENT.requestBatchNo:
                                    {
                                        L3INTF_BATCH.ResponseIntfBatch(kvp.Key);
                                        break;
                                    }
                                case L3INTF_EVENT.checkConnect:
                                    {
                                        CheckConnect(kvp.Key);
                                        break;
                                    }
                                default:
                                    {
                                        break;
                                    }
                            }
                        }
                    }

                    //只有L3 返回状态是 -1 的要处理，其余的都不管
                    Dictionary<int, L2INFT_EVENT_RESULT> dicL2 = L2INTF_EVENT.MonitorL2Infc_Event();
                    if (dicL2 != null && dicL2.Count > 0)
                    {
                        foreach (KeyValuePair<int, L2INFT_EVENT_RESULT> kvp in dicL2)
                        {
                            switch (kvp.Value.eventCode)
                            {
                                case L2INTF_EVENT.requestBatchNo:
                                    {

                                        L2INTF_BATCH.ResponseIntfBatchFaild(kvp.Key);
                                        //如果时间执行成功
                                        //if (kvp.Value.eventStatus == "2")
                                        //{
                                        //    L3INTF_BATCH.ResponseIntfBatch(kvp.Key);
                                        //}
                                        //else
                                        //{
                                        //    L2INTF_BATCH.ResponseIntfBatchFaild(kvp.Key);
                                        //}


                                        break;
                                    }
                                default:
                                    {
                                        //close all events
                                        L2INTF_EVENT.CloseEvent(kvp.Key, "-2");
                                        break;
                                    }
                            }
                        }
                    }


                    await Task.Delay(10000);
                }
                catch (Exception ex)
                {
                    LogHelper.WriteLog("MonitorL3Event", ex);
                    await Task.Delay(10000);
                }
            }
        }

        public void CheckConnect(string eventNo)
        {
            //try
            //{
            //    string sql = string.Format("select * from {0} where {1}='{2}'", L3INTF_EVENT.tableName, L3INTF_EVENT.fd_eventNo, eventNo);
            //    DataTable dataTable = OracleHelper.Exct_QueryTable(sql);
            //    if (dataTable.Rows.Count > 0)
            //    {
            //        string l3infcEventsql = string.Format("update {0} set {1}={2} where {3}={4}", L3INTF_EVENT.tableName, L3INTF_EVENT.fd_eventStatus, "2", L3INTF_EVENT.fd_eventNo, eventNo);
            //        List<string> sqlList = new List<string>();
            //        sqlList.Add(l3infcEventsql);
            //        OracleHelper.ExecuteSqlTran(sqlList);
            //        Dispatcher.Invoke(new Action(delegate
            //        {
            //            rect_L2L3.Fill = Brushes.Green;
            //            // If there are other operations can also be written here
            //        }));

            //    }
            //    else
            //    {
            //        Dispatcher.Invoke(new Action(delegate
            //        {
            //            rect_L2L3.Fill = Brushes.Red;
            //        }));
            //    }
            //}
            //catch (Exception ex)
            //{
            //    LogHelper.WriteLog("CheckConnect", ex);
            //}
        }
        #endregion
    }
}
